#include "requirement_detail_widget.h"
#include "ui_requirement_detail_widget.h"
#include "sqlite_manager.h"
#include "easylogging++.h"
#include "requirement_info_table.h"
#include "prj_manager_task_widget.h"
#include "requirement_associate_task_table.h"
#include "requirement_associate_with_task_detail_view.h"
#include "list_widget_item_widget.h"
#include "drop_selector.h"
#include <QUuid>
#include <QDebug>
#include <QStyledItemDelegate>
#include "system_config_info.h"

RequirementDetailWidget::RequirementDetailWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::RequirementDetailWidget)
{
    ui->setupUi(this);
    initUi();
    initEvents();
}

RequirementDetailWidget::~RequirementDetailWidget()
{
    delete ui;
}

void RequirementDetailWidget::setRequirementUuid(QString uuid)
{
    if (m_requirementUuid == uuid)
    {
        return ;
    }

    m_requirementUuid = uuid;
    initRequirementData(uuid);
    initAssociateTasks(uuid);
}

void RequirementDetailWidget::initUi()
{
    setAttribute(Qt::WA_StyledBackground);
    QFont font;
    font.setFamily("Courier");
    font.setStyleHint(QFont::Monospace);
    font.setFixedPitch(true);
    font.setPointSize(10);

    QTextEdit* editor = new QTextEdit();
    editor->setFont(font);
    const int tabStop = 4;  // 4 characters
    QFontMetrics metrics(font);

    ui->listWidget->setMouseTracking(true);

    ui->requirementDescriptionTextEdit->setFont(font);
    ui->requirementDescriptionTextEdit->setTabStopDistance(tabStop * metrics.averageCharWidth());
    ui->requirementNameLineEdit->setReadOnly(true);
    ui->requirementDescriptionTextEdit->setReadOnly(true);
    ui->editBtn->show();
    ui->cancelBtn->hide();
    ui->saveBtn->hide();

    QStyledItemDelegate* itemDelegate = new QStyledItemDelegate();

    initIcon();
}

void RequirementDetailWidget::initEvents()
{
    connect(ui->editBtn, &QPushButton::clicked, this, [=]() {
        ui->editBtn->hide();
        ui->cancelBtn->show();
        ui->saveBtn->show();
        ui->requirementNameLineEdit->setReadOnly(false);
        ui->requirementDescriptionTextEdit->setReadOnly(false);
    });
    connect(ui->cancelBtn, &QPushButton::clicked, this, [=]() {
        ui->requirementNameLineEdit->setReadOnly(true);
        ui->requirementDescriptionTextEdit->setReadOnly(true);
        ui->editBtn->show();
        ui->cancelBtn->hide();
        ui->saveBtn->hide();
        initRequirementData(m_requirementUuid);
    });
    connect(ui->saveBtn, &QPushButton::clicked, this, &RequirementDetailWidget::onSaveBtnClicked);
    connect(ui->associateTaskBtn, &QPushButton::clicked, this, &RequirementDetailWidget::onAssociateTaskBtnClicked);

    connect(ui->status, &DisplayInfoButton::clicked, this, [=](){
        LOG(INFO) << "responsible display info button clicked!";
        DropSelector *selector = new DropSelector;
        QRect statusGeometry = ui->status->geometry();
        QPoint selectorPos = {statusGeometry.x(), statusGeometry.bottom()};
        selectorPos = ui->status->parentWidget()->mapToGlobal(selectorPos);
        selector->setFixedWidth(statusGeometry.width());
        selector->move(selectorPos.x(), selectorPos.y());
        selector->show();
        connect (selector, &DropSelector::itemSelected, this, [=](QString text){
            LOG(INFO) << "selected text: " << text.toStdString();
            ui->status->setValue(text);
            RequirementInfoTable rit;
            rit.updateRequirementStatus(m_requirementUuid, text);
            delete selector;
        });
    });

    connect(ui->priority, &DisplayInfoButton::clicked, this, [=](){
        LOG(INFO) << "responsible display info button clicked!";
        DropSelector *selector = new DropSelector;
        selector->setItems({QStringLiteral("高"), QStringLiteral("中"), QStringLiteral("低")});
        QRect statusGeometry = ui->priority->geometry();
        QPoint selectorPos = {statusGeometry.x(), statusGeometry.bottom()};
        selectorPos = ui->status->parentWidget()->mapToGlobal(selectorPos);
        selector->setFixedWidth(statusGeometry.width());
        selector->move(selectorPos.x(), selectorPos.y());
        selector->show();
        connect (selector, &DropSelector::itemSelected, this, [=](QString text){
            LOG(INFO) << "selected text: " << text.toStdString();
            ui->status->setValue(text);
            RequirementInfoTable rit;
            rit.updateRequirementStatus(m_requirementUuid, text);
            delete selector;
        });
    });
}

void RequirementDetailWidget::initRequirementData(QString uuid)
{
    QList<QString> fields(
        {
            "requirement_name",
            "requirement_description",
            "requirement_status",
            "prj_uuid"
        }
    );
    QList<QVariantList> data;
    QHash<QString, QVariant> whereConditions;
    whereConditions["uuid"] = uuid;
    SqliteManager sm;
    bool ret = sm.selectData("requirement_info", fields, whereConditions, data);

    if (!ret || data.empty())
    {
        return ;
    }

    ui->requirementNameLineEdit->setText(data[0][0].toString());
    ui->requirementDescriptionTextEdit->setText(data[0][1].toString());
    QString status = data[0][2].toString();
    ui->status->setValue(status);
    m_prjUuid = data[0][3].toString();
}

void RequirementDetailWidget::initAssociateTasks(QString requirementUuid)
{
    RequirementAssociateWithTaskDetailView rawtd;
    QList<QVariantList> data;
    bool ret = rawtd.selectByRequirementUuid(requirementUuid,
    {
        "uuid", "requirement_uuid", "requirement_name", "task_uuid", "task_name"
    },
    data);

    if (!ret) {
        LOG(ERROR) << "get associate task failed!";
        return ;
    }

    ui->listWidget->clear();

    for (int i = 0; i < data.count(); i++) {
        addNewAssociateTaskListItem(
                data[i][4].toString(),
                data[i][0].toString(),
                data[i][1].toString(),
                data[i][3].toString());
    }
}

void RequirementDetailWidget::addNewAssociateTaskListItem(
        QString text,
        QString uuid,
        QString requirement_uuid,
        QString task_uuid)
{
    QListWidgetItem *item = new QListWidgetItem;
    QHash<QString, QString> data;
    data["uuid"] = uuid;
    data["requirement_uuid"] = requirement_uuid;
    data["task_uuid"] = task_uuid;
    item->setData(Qt::UserRole, QVariant::fromValue(data));
    item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
    ui->listWidget->addItem(item);
    ListWidgetItemWidget *itemWidget = new ListWidgetItemWidget;
    itemWidget->setText(text);
    ui->listWidget->setItemWidget(item, itemWidget);

    connect(itemWidget, &ListWidgetItemWidget::deleteItem, this, [=]() {
        LOG(DEBUG) << "delete associate task btn clicked...";
        QPoint mousePos = ui->listWidget->mapFromGlobal(QCursor::pos());
        QListWidgetItem *item = ui->listWidget->itemAt(mousePos);
        if (nullptr != item)
        {
            RequirementAssociateTaskTable ratt;
            QHash<QString, QString> data = item->data(Qt::UserRole).value<QHash<QString, QString>>();
            bool ret = ratt.deleteOneAssociate(data["uuid"]);
            if (ret) {
                ui->listWidget->takeItem(ui->listWidget->row(item));
                delete item;
            }
        }
        else {
            LOG(DEBUG) << "no available item find...";
        }
    });
}

void RequirementDetailWidget::initIcon()
{
    QIcon requirementIteratorIcon(":/resources/images/iterator.png");
    QIcon requirementComefromIcon(":/resources/images/requirement_from.png");
    QIcon requirementCategoryIcon(":/resources/images/requirement_category.png");
    QIcon requirementStatus(":/resources/images/status.png");

    ui->iterate->setInfo(requirementIteratorIcon, QStringLiteral("所属迭代"), QStringLiteral("V0.0.0"));
    ui->responsible->setInfo(requirementComefromIcon, QStringLiteral("责任人"), QStringLiteral("范贵川"));
    ui->priority->setInfo(requirementCategoryIcon, QStringLiteral("优先级"), QStringLiteral("高"));
    ui->status->setInfo(requirementCategoryIcon, QStringLiteral("当前状态"), QStringLiteral("未开始"));
}

void RequirementDetailWidget::setRequirementIterator(QString iterator)
{

}

void RequirementDetailWidget::onSaveBtnClicked()
{
    QHash<QString, QVariant> data;
    data["requirement_name"] = ui->requirementNameLineEdit->text();
    data["requirement_description"] = ui->requirementDescriptionTextEdit->toPlainText();
    QHash<QString, QVariant> whereConditions;
    whereConditions["uuid"] = m_requirementUuid;
    SqliteManager sm;
    bool ret = sm.updateData("requirement_info", data, whereConditions);
    if (!ret)
    {
        LOG(ERROR) << "update data failed, error info: "
                   << sm.lastError().toStdString();
    }

    ui->requirementNameLineEdit->setReadOnly(true);
    ui->requirementDescriptionTextEdit->setReadOnly(true);
    ui->editBtn->show();
    ui->cancelBtn->hide();
    ui->saveBtn->hide();
}

void RequirementDetailWidget::onAssociateTaskBtnClicked()
{
    PrjManagerTaskWidget *pmtw = new PrjManagerTaskWidget;
    pmtw->setWindowFlags(Qt::Window);
    pmtw->setPrjUuid(m_prjUuid);
    pmtw->setTaskSelectMode();
    connect(pmtw, &PrjManagerTaskWidget::accept, this, [=]() {
        QHash<QString, QString> checkedItems = pmtw->getCheckedTasks();
        RequirementAssociateTaskTable ratt;
        foreach (const QString &key, checkedItems.keys()) {
            QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces);
            bool ret = ratt.insertNewAssociate(uuid, m_requirementUuid, key);
            if (ret) {
                addNewAssociateTaskListItem(checkedItems.value(key),
                                            uuid, m_requirementUuid, key);
            }

        }

        pmtw->deleteLater();
    });

    connect(pmtw, &PrjManagerTaskWidget::reject, this, [=]() {
        pmtw->deleteLater();
    });
    pmtw->show();
}
